#include "Config.h"
#include "FileUtil.h"
#include "StringUtil.h"

namespace BASE{
	CConfig::CConfig():lastModifyTime(0){

	}

	bool CConfig::loadFile(const std::string & _fileName){
		fileName = _fileName;
		std::ifstream ifs(fileName.c_str(), std::ios::binary);
		if (!ifs.is_open()){
			return false;
		}
		lastModifyTime = FileUtil::getModifyTime(_fileName);
		loadStream(ifs);
		ifs.close();
		return true;
	}

	bool CConfig::isModified(){
		time_t newModifyTime = FileUtil::getModifyTime(fileName);
		return lastModifyTime != newModifyTime;
	}

	void CConfig::reload(){
		std::ifstream ifs(fileName.c_str(), std::ios::binary);
		if (!ifs.is_open()){
			return;
		}
		loadStream(ifs);
		ifs.close();
	}

	bool CConfig::getBoolValue(const std::string & key, const bool defaultVal){
		std::string val = getStringValue(key, "");
		if (val.empty()){
			return defaultVal;
		}
		return getBool(val);
	}

	int CConfig::getIntValue(const std::string & key, const int defaultVal){
		std::string val = getStringValue(key);
		if (val.empty()){
			return defaultVal;
		}
		return getInt(val);
	}

	double CConfig::getDoubleValue(const std::string & key, const double defaultVal){
		std::string val = getStringValue(key);
		if (val.empty()){
			return defaultVal;
		}
		return getDouble(val);
	}

	std::string CConfig::getStringValue(const std::string & key, const std::string defaultVal){
		Lock lock(mutex);
		ConfigValues::iterator iter = values.find(key);
		if (iter == values.end()){
			return defaultVal;
		}
		return iter->second;
	}

	void CConfig::loadStream(std::ifstream & ifs){
		ConfigValues configVal;
		std::string line;
		while(!ifs.eof()){
			std::getline(ifs, line);
			//std::cout << "line " << line << std::endl;
			if ((line.find("#") != std::string::npos) || (line.find("//") != std::string::npos)){
				continue;
			}
			size_t pos = line.find("=");
			if (pos == std::string::npos){
				continue;
			}
			std::string key = line.substr(0, pos);
			std::string val = line.substr(pos + 1);
			key = trim(key);
			val = trim(val);
			//std::cout << key << "," << val << std::endl;
			configVal.insert(std::make_pair(key, val));
		}
		Lock lock(mutex);
		values.swap(configVal);
	}
}
